<?php
// Copyright 2019 Hackware SpA <human@hackware.cl>
// "Hackware Web Services Core" is released under the MIT License terms.

namespace Hawese\Core\Http\Controllers;

use Illuminate\Support\Collection;
use Illuminate\Database\Query\Builder;

class Paginator
{
    private $db_query;
    private $current_page;
    private $items_limit;

    public function __construct(
        Builder $db_query,
        int $current_page,
        int $items_limit
    ) {
        $this->db_query = $db_query;
        $this->current_page = $current_page;
        $this->items_limit = $items_limit;
    }

    private function offset() : int
    {
        return ($this->current_page - 1) * $this->items_limit;
    }

    private function pagedDbQuery() : Builder
    {
        return $this->db_query
            ->offset($this->offset())
            ->limit($this->items_limit);
    }

    private function totalItems() : int
    {
        return $this->db_query->count();
    }

    private function prevPage()
    {
        if ($this->current_page === 1) {
            return 1;
        }
        return $this->current_page - 1;
    }
    
    private function nextPage()
    {
        if ($this->current_page === $this->totalPages()) {
            return $this->totalPages();
        }
        return $this->current_page + 1;
    }

    public function totalPages() : int
    {
        return ceil($this->totalItems() / $this->items_limit);
    }

    public function get() : Collection
    {
        return $this->pagedDbQuery()->get();
    }

    public function links(string $url, array $query_params = []) : array
    {
        $page_numbers = [
            'first' => 1,
            'last' => $this->totalPages(),
            'prev' => $this->prevPage(),
            'next' => $this->nextPage(),
        ];

        $new_query_params = array_map(function ($value) use ($query_params) {
            return array_merge(
                $query_params,
                ['page' => $value, 'limit' => $this->items_limit]
            );
        }, $page_numbers);

        // TODO: Prev and next should be null if I'm in first and last page respectively
        return array_map(function ($value) use ($url) {
            return "$url?" . http_build_query($value);
        }, $new_query_params);
    }
}
